( LOAD SCREEN FOR LINE EDITOR MVP-FORTH) 61 78 THRU ( <MATCH> MVP-FORTH) WARNING @ 0 WARNING ! : <MATCH> ( ADDR-3, ADDR-2, COUNT-1 --- FLAG ) ?DUP IF OVER + SWAP DO DUP C@ I C@ - IF 0= LEAVE ELSE 1+ THEN LOOP ELSE DROP 0= THEN ; 2 18 THRU \ load rest of editor file ( MATCH MVP-FORTH) : MATCH ( CURSOR ADDR-4, BYTES LEFT-3, STRING ADDR-2 ) ( STRING COUNT-1, --- FLAG-2, CURSOR OFFSET-1 ) >R >R DDUP R> R> DSWAP OVER + SWAP ( CADDR-6, BLEFT-5, $ADDR-4, $LEN-3, CADDR+BLEFT-2, CADDR-1 ) DO DDUP I SWAP <MATCH> IF >R DDROP R> - I SWAP - 0 SWAP 0 0 LEAVE ( CADR, BLEFT, $ADDR, $LEN OR 0, OFFSET, 0, 0 ) THEN LOOP DDROP ( CADDR-2, BLEFT-1 OR 0-2, OFFSET-1 ) SWAP 0= SWAP ; ( LINE MVP-FORTH) BASE @ HEX : LINE ( RELATIVE TO SCR, LEAVE ADDRESS OF LINE ) DUP FFF0 AND ABORT" NOT ON CURRENT EDITING SCREEN" SCR @ <LINE> DROP ; BASE ! : WIPE SCR @ CLEAR ; ( EDITOR #LOCATE MVP-FORTH) VOCABULARY EDITOR IMMEDIATE BASE @ HEX EDITOR DEFINITIONS : #LOCATE ( --- CURSOR OFFSET-2, LINE-1 ) R# @ C/L /MOD ; BASE ! ( #LEAD #LAG -MOVE BUF-MOVE MVP-FORTH) : #LEAD ( --- CURSOR ADDR-2, OFFSET TO CURSOR-1 ) #LOCATE LINE SWAP ; : #LAG ( --- CURSOR ADDR-2, COUNT AFTER CURSOR-1 ) #LEAD DUP >R + C/L R> - ; : -MOVE ( MOVE FORM ADDR-2, TO LINE-1 --- ) LINE C/L CMOVE UPDATE ; : BUF-MOVE ( MOVE TEXT TO BUFFER-1, IF ANY --- ) HERE C@ IF PAD SWAP C/L 1+ CMOVE ELSE DROP THEN ; ( >LINE# FIND-BUF INSERT-BUF MVP-FORTH) BASE @ HEX : >LINE# ( CONVERT CURRENT CURSOR POSITION TO LINE# ) #LOCATE SWAP DROP ; : FIND-BUF ( BUFFER USED FOR ALL SEARCHES ) PAD 50 + ; : INSERT-BUF ( BUFFER USED FOR ALL INSERTIONS ) FIND-BUF 50 + ; BASE ! ( HOLD- <KILL> <SPREAD> X MVP-FORTH)BASE @ HEX : <HOLD> ( MOVE LINE-1 FROM BLOCK TO INSERT BUFFER ) LINE INSERT-BUF 1+ C/L DUP INSERT-BUF C! CMOVE ; : <KILL> ( ERASE LINE-1 WITH BLANKS ) LINE C/L BLANK UPDATE ; : <SPREAD> ( SPREAD, MAKING LINE# BLANK ) >LINE# DUP 0E DO I LINE I 1+ -MOVE -1 +LOOP <KILL> ; : X ( DELETE LINE# FROM BLOCK, PUT IN INSERT BUFFER) >LINE# DUP <HOLD> 0F DUP ROT DO I 1+ LINE I -MOVE LOOP <KILL> ; BASE ! ( DISPLAY-CURSOR T L MVP-FORTH) BASE @ HEX : DISPLAY-CURSOR ( --- ) CR SPACE #LEAD TYPE 5E EMIT #LAG TYPE #LOCATE 2 .R SPACE DROP ; : T ( type line#-1 ) C/L * R# ! DISPLAY-CURSOR ; : L ( list current screen ) SCR @ LIST DISPLAY-CURSOR ; BASE ! ( N B (TOP SEEK-ERROR MVP-FORTH) : N ( SELECT NEXT SEQUENTIAL SCREEN ) 1 SCR +! ; : B ( SELECT PREVIOUS SEQUENTIAL SCREEN ) -1 SCR +! ; : <TOP> ( RESET CURSOR TO TOP OF BLOCK ) 0 R# ! ; : SEEK-ERROR ( OUTPUT ERROR MSG IF NO MATCH ) <TOP> FIND-BUF HERE C/L 1+ CMOVE HERE COUNT TYPE ." NONE" QUIT ; ( <R> P MVP-FORTH) BASE @ HEX : <R> ( REPLACE CURRENT LINE WITH INSERT BUFFER ) >LINE# INSERT-BUF 1+ SWAP -MOVE ; : P ( FOLLOWING TEXT IN INSERT BUFFER AND LINE ) 5E TEXT INSERT-BUF BUF-MOVE <R> ; BASE ! ( 1LINE MVP-FORTH) : 1LINE ( SCAN CURRENT LINE FOR MATCH WITH FIND BUFFER ) ( UPDATE CURSOR, RETURN BOOLEAN ) #LAG FIND-BUF COUNT MATCH R# +! ; ( <SEEK> <DELETE> MVP-FORTH)BASE @ HEX : <SEEK> ( FIND BUFFER MATCH OVER FULL SCREEN, ELSE ERROR ) BEGIN 3FF R# @ < IF SEEK-ERROR THEN 1LINE UNTIL ; : <DELETE> ( BACKWARDS AT CURSOR BY COUNT-1 ) >R #LAG + R@ - ( SAVE BLANK FILL LOCATION ) #LAG R@ NEGATE R# +! ( BACK AT CURSOR ) #LEAD + SWAP CMOVE R> BLANK UPDATE ; ( FILL FROM END OF TEXT ) BASE ! ( <F> F <E> E MVP-FORTH)BASE @ HEX : <F> ( FIND OCCURANCE OF FOLLOWING TEXT ) 5E TEXT FIND-BUF BUF-MOVE <SEEK> ; : F ( FIND AND DISPLAY FOLLOWING TEXT ) <F> DISPLAY-CURSOR ; : <E> ( ERASE BACKWARDS FROM CURSOR ) FIND-BUF C@ <DELETE> ; : E ( ERASE AND DISPLAY LINE ) <E> DISPLAY-CURSOR ; BASE ! ( D TILL MVP-FORTH) BASE @ HEX : D ( FIND, DELETE, AND DISPLAY FOLLOWING TEXT ) <F> E ; : TILL ( DELETE FROM CURSOR TO TEXT END ) #LEAD + 5E TEXT FIND-BUF BUF-MOVE 1LINE 0= IF SEEK-ERROR THEN #LEAD + SWAP - <DELETE> DISPLAY-CURSOR ; BASE ! ( COUNTER BUMP MVP-FORTH) BASE @ HEX VARIABLE COUNTER 0 COUNTER ! : BUMP ( THE LINE NUMBER AND HANDLE PAGING ) 1 COUNTER +! COUNTER @ 38 > IF 0 COUNTER ! CR CR 0C EMIT THEN ; BASE ! ( S MVP-FORTH) BASE @ HEX : S ( FROM CURRENT TO SCREEN-1 FOR STRING ) 0C EMIT 5E TEXT 0 COUNTER ! FIND-BUF BUF-MOVE SCR @ DUP >R DO I SCR ! <TOP> BEGIN 1LINE IF DISPLAY-CURSOR SCR ? BUMP THEN 3FE R# @ < ?TERMINAL IF 1 ELSE 0 THEN OR UNTIL PAUSE ?TERMINAL IF KEY DROP LEAVE THEN LOOP R> SCR ! ; BASE ! ( I U MVP-FORTH)BASE @ HEX : I ( INSERT TEXT WITHIN LINE ) 5E TEXT ( LOAD INSERT BUFFER WITH TEXT ) INSERT-BUF BUF-MOVE ( IF ANY ) INSERT-BUF COUNT #LAG ROT OVER MIN >R R@ R# +! ( BUMP CURSOR ) R@ - >R ( CHARACTERS TO SAVE ) DUP HERE R@ CMOVE ( FROM OLD CURSOR TO HERE ) HERE #LEAD + R> CMOVE ( HERE TO CURSOR LOCATION ) R> CMOVE UPDATE ( PAD TO OLD CURSOR ) DISPLAY-CURSOR ; ( LOOK AT NEW LINE ) : U ( INSERT FOLLOWING TEXT UNDER CURRENT LINE ) C/L R# +! <SPREAD> P ; BASE ! ( R M MVP-FORTH) : R ( REPLACE FOUND TEXT WITH INSERT BUFFER ) <E> I ; : M ( MOVE FROM CURRENT LINE ON CURRENT SCREEN ) SCR @ >R ( TO SCREEN-2, UNDER LINE-1 ) R# @ >R ( SAVE ORIGINAL SCREEN AND CURSOR LOCATION ) >LINE# <HOLD> ( MOVE CURRENT LINE TO INSERT BUFFER ) SWAP SCR ! ( SET NEW SCREEN # ) 1+ C/L * R# ! ( TEXT IS STORED UNDER REQUESTED LINE ) <SPREAD> <R> ( STORE INSERT BUFFER IN NEW SCREEN ) R> C/L + R# ! ( SET ORIGINAL CURSOR TO NEXT LINE ) R> SCR ! ; ( RESTORE ORIGINAL SCREEN ) FORTH DEFINITIONS ( Value on stack ) WARNING !